2024 Spanish Grand Prix¶

Hola gerentes and welcome to the Fantasy League report for the 2024 Spanish Grand Prix. The penultimate Spanish Grand Prix at the Circuit de Barcelona-Catalunya, perhaps forever. The historic testing circuit is finally getting dropped from the calendar after going through numerous changes in the last two decades; including a re-profiling of turns 9 and 10, the fast right and hairpin for the higher downforce cars, even a chicane to slow cars down, which was recently removed in the final corners to allow for faster speeds on the pit straight. But it has clearly not worked the way F1 wanted it to and has been dropped in favour of a brand new Madrid circuit from 2026 onwards. I don't want to sound like a boomer F1 fan, but I really dislike this "this circuit doesn't work so let's build a new one" vibe that F1 are going for at the moment. I like the historical tracks, even Barcelona. It's seen some improvement since the removal of the final chicane and the removal as F1's testing circuit in recent years. But I don't make the rules or the calendar....yet.

No real big news this week as rumours begin to circle once again that Carlos Sainz has signed for Williams. Nothing is confirmed yet, and as far as we know the Spanish driver could end up literally anywhere in 2025 and beyond. The current leading suggestions are that he will end up at Kick Sauber or Williams, which will be his fifth team in 10 years. His performances of late haven't set the world on fire, but at the start of the season he was hot property, having been the only driver in 2023 to beat Max Verstappen, now however he is not as desireable as the other drivers in the field. Only time will tell where Carlos will end up, or what he will end up doing, but it's sad to see him fall from grace like this. Speaking of falling from grace, Esteban Ocon is again touting that he has secured a drive for 2025 after the recent departure from Alpine. The Frenchman's claims come as very few seats are left on the grid, leading many to believe he will be driving for Haas next year. I could see this happening, but I can't see Ocon and Magnussen at the same team, and that team being able to financially make it to the Saudi Arabian Grand Prix. Could this be a surprise re-exit for Magnussen? Or has Ocon signed for Kick/Williams in a surprise move?

The wolves are circling for Logan Sargeant as the American driver's future is in question. Logan was given all the support and encouragement in the world from team boss James Vowles last year, but it seems that the favour has run out of late. Even the mildly mid David Coulthard took a few shots at Logan this weekend. In a segment for Dutch TV, similar to Ted's Notebook, David can be seen in the drivers' car park commenting on the parking capabilities of a certain "Mercedes Engined Car" having hit a bollard in the car park. He later reveals that this is Logan's car and that he has "hit something before even getting on the circuit". The savage clip is doing the rounds, but I'm not sure the Scot is really the man to be talking about hitting things he shouldn't have..... Belgium.

The rumours of Newey going to Ferrari seem to have died down once again, with an Italian media outlet reporting that the Brit had been offered one of the largest contracts in F1 history to come and work for the Scuderia in 2026 and beyond, but that an announcement was yet to officially be made. Aston Martin took this personally, it seems, as they came out and publically announced they were going to write Newey a "blank cheque" type deal to secure the mastermind of the aero generation. It does seem like Newey is only hot property because of the recent success of the Red Bull team, despite the 2026 regulations going more towards the power unit. It's an odd move to fight over him, for sure, particularly as the 2014-2017 Red Bull cars didn't exactly set the world on fire. Again, just another moving piece of the silly season jigsaw that we all can't wait to land.

In [ ]:
import os
import subprocess
import src.dataIO as io
import src.webDataIO as wio

from pathlib import Path

year = 2024
race = 'Spain'

Grand Prix Report¶

Free practice saw three different drivers top the sessions, with it nearly being an all-British affair. Norris topped FP1, Hamilton topped FP2, and Norris very nearly topped FP3 until Sainz displaced him in the dying moments. The Spaniard clearly egged on by his home crowd, which reportedly sold out his grandstand in 8 minutes, with many being turned away for tickets or displaced around the circuit.

Sprint Qualifying¶

No Sprint Qualifying To Report.

In [ ]:
#wio.outputs_sq_data(
#    year=year,
#    race=race)

Sprint Race¶

No Sprint Race To Report.

In [ ]:
#wio.outputs_sprint_data(
#    year=year,
#    race=race)

Qualifying Report¶

Qualifying was close, as it has been in many of the sessions lately and continues to get even closer. The gap from first to last in Q1 was slightly over a second, and that's all there was to play for. Luckily for some up and down the grid, there were no major shock exits in Q1. Yes that's right folks, Sergio Perez finally made it out of Q1. Shock. Anyway, Logan Sargeant finished last in qualifying, the American driver finally running a fully upgraded Williams, in the hopes that this is the reason he has been so far behind Albon of late. Many of his fans, yes many, are suggesting that he is still emotionally shaken by the driver swap in Australia. Quite frankly, he is an F1 driver, get over it. If you can't, you don't deserve to be here. He was joined by teammate Alex Albon, Daniel Ricciardo, Yuki Tsunoda, and Kevin Magnussen. The RBs really didn't look good at all this weekend, despite a major upgrade package being added to the car. At least the pair of them went fairly under the radar this week with no major issues for either of them, so they can indeed blame the car.

Q2's biggest shock was the elimination of home-hero Fernando Alonso and his teammate Lance Stroll, it's become a bit of a running theme that Stroll is eliminated early in qualifying, but we can usually rely on Fernando to go the distance. That Aston Martin is in dire need of some performance upgrades to stay in the top 10. It seems to be that they are falling into the clutches of Alpine, pace wise, and that could provide quite the spicy mid-field fight throughout the season. They've been relatively unchallenged up until now, not really able to fight with the big 4, and much faster than the bottom 5, but now there's some real skin in the game. They were joined by Valtteri Bottas, Zhou Guanyu, and Nico Hulkenberg. I believe this is Zhou's best qualifying for quite some time, has the Kick finally got some pace? Or is Zhou just pretty good around Barcelona? Who knows. It's really hard to tell who has pace at this track given the amount of data the teams have available to them.

Q3 turned up the wick with potentially 8 drivers in the fight for pole position. Alpine's Pierre Gasly and Esteban Ocon both made it into Q3 for the first time this year, I think I'm right in saying that. The Alpine team turning things around very quickly mid-season to bring some pace back to that car. They weren't in the fight though, despite putting in some pretty stellar lap times early on. It seemed to be between Max, Lando, and Lewis for pole though, with the Ferrari boys occasionally putting in some very quick times. Oscar Piastri was on an absolute beast of a lap until he ran wide into the gravel and had to abandon his lap, leaving teammate Lando Norris to swoop in and take a last minute pole position by 0.02 seconds, meaning Max has missed out on pole in the last two races by 0.02 seconds, the smallest margin in the history of the sport across two races. Lewis Hamilton beat George Russell for only the third time this year, ahead of the Ferrari duo and Perez who was carrying a penalty from the Canadian Grand Prix. He was still beaten by Pierre Gasly though, on merit, which is quite something from the Frenchman.

In [ ]:
wio.outputs_qualifying_data(
    year=year,
    race=race)
Pos No Driver Car Q1 Q2 Q3 Laps
1 4 Lando Norris NOR McLaren Mercedes 1:12.386 1:11.872 1:11.383 12
2 1 Max Verstappen VER Red Bull Racing Honda RBPT 1:12.306 1:11.653 1:11.403 12
3 44 Lewis Hamilton HAM Mercedes 1:12.143 1:11.792 1:11.701 18
4 63 George Russell RUS Mercedes 1:12.456 1:11.812 1:11.703 16
5 16 Charles Leclerc LEC Ferrari 1:12.257 1:12.038 1:11.731 12
6 55 Carlos Sainz SAI Ferrari 1:12.403 1:11.874 1:11.736 12
7 10 Pierre Gasly GAS Alpine Renault 1:12.651 1:12.079 1:11.857 18
8 11 Sergio Perez PER Red Bull Racing Honda RBPT 1:12.477 1:12.054 1:12.061 18
9 31 Esteban Ocon OCO Alpine Renault 1:12.691 1:12.109 1:12.125 18
10 81 Oscar Piastri PIA McLaren Mercedes 1:12.460 1:12.011 DNF 16
11 14 Fernando Alonso ALO Aston Martin Aramco Mercedes 1:12.505 1:12.128 12
12 77 Valtteri Bottas BOT Kick Sauber Ferrari 1:12.758 1:12.227 12
13 27 Nico Hulkenberg HUL Haas Ferrari 1:12.708 1:12.310 12
14 18 Lance Stroll STR Aston Martin Aramco Mercedes 1:12.881 1:12.372 15
15 24 Zhou Guanyu ZHO Kick Sauber Ferrari 1:12.880 1:12.738 15
16 20 Kevin Magnussen MAG Haas Ferrari 1:12.937 6
17 22 Yuki Tsunoda TSU RB Honda RBPT 1:12.985 9
18 3 Daniel Ricciardo RIC RB Honda RBPT 1:13.075 9
19 23 Alexander Albon ALB Williams Mercedes 1:13.153 6
20 2 Logan Sargeant SAR Williams Mercedes 1:13.509 9

Race Report¶

So this particular F1 fan missed the start of the race by a whopping 40 minutes. Yep that's right, I thought the race started at 3, tuned in at 2:40 to listen to the grid walk to find Lando Norris overtaking Lewis Hamilton on lap 33. Quite the blunder. I have since watched the highlights on YouTube and have some sort of idea what happened. So Max Verstappen dominated from lap 1 and won the entire race by a huge margin as per. Report Over. Just kidding. Of course I saw Lando getting a poor start and pushing Max onto the grass going down one of the longest straights on the calendar as the two were far too focussed on each other. Let me just add, if that was Max doing that, we'd all be losing our minds as to how aggressive he was being. But no, no one dare say a bad thing about Lando, except me. It was pretty dangerous for Lando to do that off the line, yes they aren't going full speed but they are full of fuel and there are far too many cars around them to be pushing someone into a lower traction zone intentionally. Thankfully, Max kept it together and no one got hurt. While they were busy fighting each other, the Mercs behind were free to attack. That is if Lewis Hamilton didn't have the reaction time of a 40 year old man. Instead it was fourth-place-starter George Russell who benefitted the most, getting a double dose of slip stream and threading the needle perfectly to take the racing line and overtake all three of them into turn 1. It didn't last long though, as Max was quick to get back through and pull out a bit of a gap ahead of the chasing Norris, who took a fair while to catch back up.

Pirelli clearly brought the correct tyre compounds this week as the race ended up being a two-stopper. Lando extended his first stint to give him fresher tyres for the second stint, around about the time I started watching, where he was able to push through the Mercs and go on to chase Max. IT became a two-horse race very quickly but Lando ran out of laps in the final soft-stint and wasn't able to beat the reigning champion to chequered flag. Mercedes split their strategy in the final stint, putting George Russell on the hard tyres and Lewis on the softs. This went down very well with teamLH who have recently come under fire for sending threats to the Mercedes team for supposedly favouring George and sabotaging Lewis. The seven-time champion got his first podium of the season, and his first in 12 races, which is pretty wild. Since Max's first win at the 2016 Spanish Grand Prix, Max has now won more races than Lewis, which is insane to think about. As for the prancing horses, well they had a pretty terrible race. As far as I can tell they were told to save tyres but Sainz decided not to do that and launched an attack at his teammate. The two collided and Sainz gained a place by running across the run-off at turn 1, an incident which went without penalty. He had a similar incident at turn 1 with Lewis, which again he wasn't too happy about. Ferrari also split their last-stint tyre strategy in favour of Leclerc, who felt he had suffered an unwarranted attack in the opening gambit. They were followed closely by the second McLaren, Piastri, who was in turn ahead of Sergio Perez by nearly a full pit stop. Let's speak about Perez for a second actually because this is simply not good enough anymore. Yes he had a penalty, but it was only a three-place penalty. He only started eleventh, and yet he has finished a minute behind Max in a 66 lap race where Max was busy fighting Lando, Mercedes, and had to make his way through a couple of Ferrari cars. It is truly not good enough for that seat. If we look at how ruthless Red Bull have been in the past for events such as this, we find that they sack or swap drivers who perform this badly. How much longer can they continue to justify his position in the team.

A truly excellent performance this weekend by the Alpine drivers. They not only managed to secure a top-ten qualifying performance, but also managed a top-ten race performance too. Now yes, they lost a place as Perez overtook them, but they maintained their qualifying position (well Ocon did), and if Piastri had actually put in a qualifying lap then they would have. It's a good turn around considering they've been nowhere for most of the season and spent recent races running into each other. I didn't spot any drama between the two of them in the half + highlights that I watched, so let me know if I've completely missed something. Guanyu Zhou and Nico Hulkenberg clearly had a good, albeit quiet, race too given that they both finished on the lead lap and ahead of their teammates. Fernando and Lance both struggled for pace throughout the race, clearly some more work needed down at Aston Martin; maybe they really do need Newey on their side to turn this disaster around as they head into the fight with Alpine. A poor weekend for RB as their upgrade package fails to take them to a victory over Kick Sauber, and a terrible weekend for Williams. Spain used to be a track that suited Williams with many of the corners high speed, but since they changed their philosophy, not so much. Sargeant was the only driver to finish 2 laps down, and Albon took a late-race trip across the gravel at the final corner and ruined his tyres. A weekend to forget and plenty of work to do going into the last two legs of the triple header. I do believe the race had no yellow flags, which is something that happened last year too, which may make it look like quite a dull race. I think, for Spain, the race was actually quite good thanks to a two-stopper and some battling at the front, but compared to recent races, it wasn't quite up to scratch.

In [ ]:
wio.outputs_race_result(
    year=year,
    race=race)
Pos No Driver Car Laps Time/Retired PTS
1 1 Max Verstappen VER Red Bull Racing Honda RBPT 66 1:28:20.227 25
2 4 Lando Norris NOR McLaren Mercedes 66 +2.219s 19
3 44 Lewis Hamilton HAM Mercedes 66 +17.790s 15
4 63 George Russell RUS Mercedes 66 +22.320s 12
5 16 Charles Leclerc LEC Ferrari 66 +22.709s 10
6 55 Carlos Sainz SAI Ferrari 66 +31.028s 8
7 81 Oscar Piastri PIA McLaren Mercedes 66 +33.760s 6
8 11 Sergio Perez PER Red Bull Racing Honda RBPT 66 +59.524s 4
9 10 Pierre Gasly GAS Alpine Renault 66 +62.025s 2
10 31 Esteban Ocon OCO Alpine Renault 66 +71.889s 1
11 27 Nico Hulkenberg HUL Haas Ferrari 66 +79.215s 0
12 14 Fernando Alonso ALO Aston Martin Aramco Mercedes 65 +1 lap 0
13 24 Zhou Guanyu ZHO Kick Sauber Ferrari 65 +1 lap 0
14 18 Lance Stroll STR Aston Martin Aramco Mercedes 65 +1 lap 0
15 3 Daniel Ricciardo RIC RB Honda RBPT 65 +1 lap 0
16 77 Valtteri Bottas BOT Kick Sauber Ferrari 65 +1 lap 0
17 20 Kevin Magnussen MAG Haas Ferrari 65 +1 lap 0
18 23 Alexander Albon ALB Williams Mercedes 65 +1 lap 0
19 22 Yuki Tsunoda TSU RB Honda RBPT 65 +1 lap 0
20 2 Logan Sargeant SAR Williams Mercedes 64 +2 laps 0

Fastest Lap¶

Fastest lap this week goes to Lando Norris, who took the fastest lap of a 1:17:115 on lap 51 of 66 just after he pitted for scrubbed softs and began to hunt down Max Verstappen ahead. The Brit also took driver of the day, which has come under fire recently as a bit of a gimmick and something that can be gamed by a particular fan base. I think it's actually much worse than it looks as it also gives you 10 points in the fantasy league when that driver is voted in, so I'm sure there are many around the world who vote based on that too, which just means it's a "who have I got this week" sort of vote. Shame really.

In [ ]:
wio.outputs_fastest_lap(
    year=year,
    race=race)
Pos No Driver Car Lap Time of day Time Avg Speed
1 4 Lando Norris NOR McLaren Mercedes 51 16:12:04 1:17.115 217.405
2 1 Max Verstappen VER Red Bull Racing Honda RBPT 54 16:15:52 1:17.776 215.557
3 11 Sergio Perez PER Red Bull Racing Honda RBPT 51 16:12:50 1:17.785 215.532
4 44 Lewis Hamilton HAM Mercedes 46 16:05:37 1:17.809 215.466
5 81 Oscar Piastri PIA McLaren Mercedes 56 16:19:02 1:17.874 215.286
6 16 Charles Leclerc LEC Ferrari 52 16:13:37 1:17.897 215.222
7 63 George Russell RUS Mercedes 50 16:10:50 1:18.290 214.142
8 14 Fernando Alonso ALO Aston Martin Aramco Mercedes 50 16:11:50 1:18.334 214.022
9 55 Carlos Sainz SAI Ferrari 39 15:56:24 1:18.539 213.463
10 27 Nico Hulkenberg HUL Haas Ferrari 49 16:10:15 1:18.609 213.273
11 24 Zhou Guanyu ZHO Kick Sauber Ferrari 50 16:11:49 1:18.771 212.834
12 31 Esteban Ocon OCO Alpine Renault 54 16:16:49 1:18.982 212.266
13 10 Pierre Gasly GAS Alpine Renault 51 16:12:41 1:19.045 212.096
14 23 Alexander Albon ALB Williams Mercedes 45 16:05:33 1:19.132 211.863
15 18 Lance Stroll STR Aston Martin Aramco Mercedes 50 16:11:54 1:19.318 211.366
16 22 Yuki Tsunoda TSU RB Honda RBPT 56 16:20:34 1:19.447 211.023
17 3 Daniel Ricciardo RIC RB Honda RBPT 61 16:26:59 1:19.450 211.015
18 77 Valtteri Bottas BOT Kick Sauber Ferrari 13 15:21:30 1:19.608 210.596
19 20 Kevin Magnussen MAG Haas Ferrari 33 15:49:12 1:19.805 210.077
20 2 Logan Sargeant SAR Williams Mercedes 38 15:56:13 1:20.172 209.115

Fantasy League Scores¶

Lineup Scores¶

Ok I think I have waffled enough, let's see what this race has done to the fantasy league standings. First let's begin with the driver/team points for the grid. The data you see below are the current total points and values for each driver and team. Values are taken going into the race and updated for next race after I submit the report.

In [ ]:
weekly_scores = {
    "Name": ["Points", "Value"],
    "Race": [f'{race}'],
    "Ocon": [45, 10.2],
    "Gasly": [48, 9.3],
    "Stroll": [44, 14.2],
    "Alonso": [92, 16.7],
    "Leclerc": [266, 23.1],
    "Sainz": [206, 21.5],
    "Bearman": ["N/A", "N/A"],
    "Magnussen": [47, 9.9],
    "Hulkenberg": [40, 8.8],
    "Bottas": [20, 8.0],
    "Guanyu": [46, 7.9],
    "Norris": [274, 25.8],
    "Piastri": [181, 21.6],
    "Hamilton": [151, 21.4],
    "Russell": [175, 20.8],
    "Tsunoda": [51, 9.6],
    "Ricciardo": [15, 9.4],
    "Verstappen": [339, 30.7],
    "Perez": [180, 22.4],
    "Albon": [-12, 8.1],
    "Sargeant": [1, 5.6],
    "Alpine": [121, 9.1],
    "Aston Martin": [194, 15.5],
    "Ferrari": [582, 22.6],
    "Haas": [114, 9.5],
    "Kick Sauber": [73, 7.3],
    "McLaren": [511, 25.6],
    "Mercedes": [431, 21.9],
    "RB": [114, 9.8],
    "Red Bull": [706, 28.8],
    "Williams": [5, 6.3]}
root = Path().absolute()
if Path(f'{root}/Data/{year}/Lineup/{race}_Results.json').is_file():
    pass
else:
    io.save_json_dicts(
        out_path=Path(f'{root}/Data/{year}/Lineup_Weekly.json'),
        dictionary=weekly_scores)
subprocess.run(["python", "lineup.py", f'{year}'])
Out[ ]:
CompletedProcess(args=['python', 'lineup.py', '2024'], returncode=0)

Lando Norris once again dominates the fantasy league scores with a whopping 51 points, leaps and bounds ahead of the reigning champion Max Verstappen who only manages 38 points despite winning. That's the power of the driver of the day vote. Next up is the Mercedes duo of Hamilton and Russell with 29 and 27, respectively, and Sergio Perez somehow rounds out the top five with 19 points. We have a trio of one-pointers at the bottom of the table, Logan Sargeant, Valtteri Bottas, and Fernando Alonso all have very "meh" races there. Then we have a bunch of four-pointers; Yuki Tsunoda, Esteban Ocon, Kevin Magnussen, Guanyu Zhou, and Alex Albon are part of that group. Lance Stroll and Nico Hulkenberg manage a pair of sixes, just behind Ricciardo and Gasly with seven points. Which means, after covering almost all of the field, Oscar Piastri rounds out the bottom five scores with 15 points.

Red Bull do take the top step this week in the constructors competition with 82 points ahead of Mercedes and McLaren who manage to tie with 66 points. They are followed by Ferrari in third with 44 points. Williams are at the bottom this week, only managing 4 points. They're joined by Kick Sauber with 8 points, and RB and Aston Martin rounding out the bottom three with 10 points each.

Max Verstappen continues his run at the top of the table with 339 points, but we do have a new second-place man in the form of Lando Norris who continues to score incredibly highly, he now has 274 points. Charles Leclerc, therefore, has dropped down to third place with 266 points, ahead of teammate Carlos Sainz in fourth with 206 points. Oscar Piastri rounds out the top five with 181 points. Alex Albon still sits at the bottom of the table, and is the only driver with negative points, he sits on -12 points, behind teammate Logan Sargeant with 1 singular point. Daniel Ricciardo is next with 15 points, just behind Valtteri Bottas with 20 points. Nico Hulkenberg rounds out the bottom five with a couple of average results lately, sitting on 40 points.

Red Bull extend their advantage at the top with 706 points, ahead of Ferrari with 582 points, not for much longer however as McLaren are hot on their heels in third with 511 points. Williams still sit at the bottom of the table with 5 points, behind Kick Sauber with 73 points. RB round out the bottom three with 114 points.

In [ ]:
points_files = [
    'Driver_Points_Bar.png',
    'Team_Points_Bar.png',
    'Driver_Sum Points.png',
    'Team_Sum Points.png']
directory_path = Path(f'{root}/Data/{year}/Figures/{race}')
file_paths = [Path(f'{directory_path}/{race}_{file}') for file in points_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None, None]

As if you thought Max couldn't get more expensive, he's gone and added an extra $0.2 to his value, taking him up to a staggering $30.7. Norris' value continues to spike too as he reaches $25.8. Leclerc drops a little to $23.1 as Perez begins his rise back up to $22.4. Oscar Piastri is your fifth expensive driver here with $21.6 going into the weekend. Logan Sargeant is still your cheapest driver in the market with a value of $5.6. He's in a league of his own at the bottom at Guanyu Zhou is next with a value of $7.9, just behind his teammate with a value of $8.0. Alex Albon next with a value of $8.1 and Hulkenberg rounds out your bottom five with a value of $8.8.

Red Bull's value remained constant going into the Spanish Grand Prix, with a value of $28.8. McLaren however continue to rise, hitting $25.6 before the race weekend began. Ferrari round out the top three with a value of $22.6. Williams are still the cheapest team on the grid, with a value of $6.3. Kick Sauber next coming in at $7.3, and Alpine round out the bottom three with a value of $9.1.

All values given in millions of dollars. Values representative of the pre-race value, i.e., how much would it cost to have them in your team for the race.

In [ ]:
average_files = [
    'Driver_Values_Bar.png',
    'Team_Values_Bar.png',
    'Driver_Average Points.png',
    'Team_Average Points.png']
directory_path = Path(f'{root}/Data/{year}/Figures/{race}')
file_paths = [
    Path(f'{directory_path}/{race}_{file}') for file in average_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None, None]

Your best value for money this week was Lando Norris, by quite a long way too, coming in at 1.98 ppm. He is leaps and bounds ahead of Lewis Hamilton and George Russel with 1.36 and 1.3 ppm, respectively. The reigning champion Max Verstappen is next up with a 1.24 ppm. His teammate Sergio Perez rounds out the top five with a 0.85 ppm. Quite unusual that we have four top drivers, and Perez, in the top five this week, usually one of the lower team drivers makes it into this list, but with no retirements, it was quite a straightforward race for those at the front. Your worst value for money was Fernando Alonso, who only managed 0.06 ppm. He's followed by Bottas with 0.12, and Logan Sargeant with 0.18 ppm. Esteban Ocon is next with 0.39 ppm, and Kevin Magnussen rounds out the bottom five with 0.4 ppm.

Constructor-wise, Mercedes were your best band-for-your-buck this week with a 3.01 ppm, ahead of reigning champions Red Bull with 2.85 ppm. A shock entry from Alpine in third with 2.64 ppm, their safe points score and qualifying performance really helping them out there. Williams just edge out Aston Martin at the bottom, the pair coming in with 0.63 and 0.65 ppm, respectively. RB round out the bottom three with 1.02 ppm.

ppm = points per million dollars.

In [ ]:
ppv_files = [
    'Driver_Points Per Value_Bar.png',
    'Team_Points Per Value_Bar.png',
    'Driver_Average Points Per Value.png',
    'Team_Average Points Per Value.png']
directory_path = Path(f'{root}/Data/{year}/Figures/{race}')
file_paths = [Path(f'{directory_path}/{race}_{file}') for file in ppv_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None, None]
In [ ]:
subprocess.run(["python", "manager.py", f'{year}'])
Out[ ]:
CompletedProcess(args=['python', 'manager.py', '2024'], returncode=0)

Manager Scores¶

It's time to see what the scores are looking like in the fantasy league between all of you. We have another new weekly winner this week, as the original fantasy league champion returns to the top step. That's right, Matty is back baby! Their team The Lizard Queen tops the board with 263 points ahead of current championship leader Stefanus with Haryanto and 239 points. A slight return to form after the blip that was Canada there. In third place, holding strong to their new performance, is Pete with Lightning McCars and 236 points. In fourth we have Josh with Siemens McLaren West with 233 points, tied with Pete and Squeshed Nintendo Racing. Rounding out the top five is Sebastian with Denso Panasonic Toyota F1 and 229 points.

In the bottom five we have a tie between Patrick and Stuart, with their teams Racing No Points and Ferrari Strategists coming in with 32 points. Close behind them is James and a return to form for Bwoah Industries, their team Bwoah Rolex Sipsmith Golf comes in at 35 points, just edging our Joe and alpine sandbags with 36 points in third. Next is Will and The Big One with 49 points, and Charlie and Lee Carvallo's F1 Challen round out the bottom five.

What has that done to the scores? Well you'll be unsurprised to know that Stefanus still dominates the top of the table, and someone really needs to topple the power. Haryanto, Syahrul, and Gelael sit first, second, and third, with 2346, 2150, and 2034 points, respectively. Patrick is still in fourth holding steady with their team Johnny UniHaas and 2004 points. Toby makes it back into the top five this week with Hesketh 2.1 and 1918, just edging Sam out of the top five.

Patrick continues to lead the way at the bottom of the table with Racing No Points and 306 points. Will and The Big One hold steady in second with 358 points. Joe and Alpine Sandbags are still in third with 373 points, and it's Stuart and Ferrari Strategists in fourth with 390 points. James and Bwoah Rolex Sipsmith Golf round out the bottom five with 407 points. That's right, just 101 points separate the top five in the Golf League.

Our biggest winner this week is Pete and Lightning McCars with 6 positions gained in the league. Josh and Siemens McLaren West begin the climb back up the table too with 5 positions gained this week. Tom, Pete, and Sebastian come in with their teams Mc Sled Dogs, Squeshed Nintendo Racing, and Denso Panasonic Toyota F1 all gaining 4 places each. Our biggest loser of the week is Val with their team My Fav'rit Colour Is Blue dropping a huge 5 places. Madlen and Jo lose 4 places each with their teams Les Eclairs and THE LONG AND WINDING ROAD. Pierce makes a double appearance next with Adam and Sebastian all losing 3 places with their teams Ferrari Champions 2026, Grazzi#44, Haas Every Name Ben Taken, and Telefonica Minardi Doimo.

In [ ]:
team_files = [
    'LeagueTeams_Points_Bar.png',
    'LeagueTeams_Sum Points_Bar.png',
    'LeagueTeams_Sum Points.png',
    'LeagueTeams_PositionsGained_Bar.png']
directory_path = Path(f'{root}/Data/{year}/Figures/{race}')
file_paths = [
    Path(f'{directory_path}/{race}_{file}') for file in team_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None, None]

A return to form for Bwoah Industries in the values department this week, they are flush for cash at the moment preparing for the big summer blowout. Manager James was unavailable for comment at their team's $121.3 value for Bwoah OnlyFans VIP Racing, though many speculate that certain pictures may be circulating the internet. Sam CJ and Stefanus are also up their in the values department with a value of $119.5 and $117.3 each. Our cheapest team on the grid is Will and The Big One, the plucky underdogs of the grid just about scraping through on shoe strings alone, they come in at a value of $51.5. Stuart and Patrick are tied on value with their teams Ferrari Strategists and Racing No Points worth $53.5 each, and Joe and alpine sandbags are in third with a slightly inflated $56.5 value. All values given in $M.

It's not all about money though, sometimes it's about what you can do with it. And this week is no different. Matty and The Lizard Queen are proving you don't need a big budget to reel in the points as they come in with a 2.33 ppm points per value. Their ahead of Pete and Squeshed Nintendo Racing with a 2.13 ppm, and Sebastian and Denso Panasonic Toyota F1 with a 2.11 ppm. To highlight just how important using your budget correctly is, Bwoah Industries, the biggest budget on the grid by far, are at the bottom of the table with their team Bwoah Rolex Sipsmith Golf coming in with a 0.59 ppm. Clearly they are laundering money through that team. Stuart and Patrick are next up with a 0.6 ppm, and Joe rounds out the bottom three with 0.64 ppm.

In [ ]:
team_files = [
    'LeagueTeams_Values_Bar.png',
    'LeagueTeams_Sum Values.png',
    'LeagueTeams_Points Per Value_Bar.png',
    'LeagueTeams_Average Points Per Value.png']
directory_path = Path(f'{root}/Data/{year}/Figures/{race}')
file_paths = [
    Path(f'{directory_path}/{race}_{file}') for file in team_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None, None]

It goes without saying that the manager at the top of the table with all three teams is also leading the total points tally. Stefanus has 6530 points ahead of Josh and Sebastian with 5263 and 5232 points, respectively. Chloe is at the bottom of the table with 1236 points, but our lowest manager with 3 teams is Pierce with 2310 points. Andrew and Stuart are the other two with 3198 and 3207 points, respectively. Poor form from Pierce as the other two are competing in the Golf League too.

Pete takes the average points of the week spot across their teams with 211 points, ahead of Stefanus with 203.33, and Josh with 196.33. Our lowest average was Patrick with 101 points, ahead of Adam with 120.33, and James with 121.67 points.

In [ ]:
manager_files = [
    'LeagueManagers_Sum Points_Bar.png',
    'LeagueManagers_Sum Points.png',
    'LeagueManagers_Average Points_Bar.png',
    'LeagueManagers_Sum Average Points.png']
directory_path = Path(f'{root}/Data/{year}/Figures/{race}')
file_paths = [
    Path(f'{directory_path}/{race}_{file}') for file in manager_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None, None]

Manager of the week this week is Pete with a 1.89 ppm, ahead of Josh with 1.78 ppm, and Stefanus with 1.77 ppm. It's very close at the top of that list for sure. Our worst manager of the week was Sam CJ with a 1.09 ppm, ahead of Pierce with 1.12 ppm, and Adam with 1.16 ppm.

In [ ]:
manager_files = [
    'LeagueManagers_Sum Values.png',
    'LeagueManagers_Average Values_Bar.png',
    'LeagueManagers_Points Per Value_Bar.png',
    'LeagueManagers_Average Points Per Value.png']
directory_path = Path(f'{root}/Data/{year}/Figures/{race}')
file_paths = [
    Path(f'{directory_path}/{race}_{file}') for file in manager_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None, None]

Yuki climbs his way back to the top of the driver selection this week with the Japanese superstar getting into 30 of the 65 teams for the Spanish Grand Prix. He pushes the reigning world champion Max Verstappen out of the way, the Dutchman dropping two counts down to 27 teams this week. He's ahead of Hulkenberg and Albon in third with 26 a piece, and Logan Sargeant in fourth with 25 selections. Kevin Magnussen and Charles Leclerc round out the top five with 23 selections. Someone has finally taken Oliver Bearman out of their team, the British super sub now only in one team on the grid, who could it be I wonder? Sergio Perez drops more selections this week after a poor performance in Monaco and Canada, the Mexican Minister of Defense now only in 6 teams. Hamilton drops a selection this week, tieing with Stroll with only 7 team selections in third place. Oscar Piastri and Carlos Sainz are next with only 8 teams choosing the number 2 drivers at Ferrari and McLaren. George Russell clambers his way into a few selections this week to round out the bottom five, the British Mercedes man is now in 9 teams on the grid.

Ferrari are clearly impressing some of you, as another selection is added to their total, they now sit in 31 of the 65 teams in this league. RB drop a selection in second with only 18, and McLaren and Haas are tied in third with 14 selections. Alpine drop yet another selection, just as they were getting good, with only 4 of you running them in your teams. Aston Martin are in second with 7 selections, and Kick Sauber round out the bottom three with 10 selections.

Max Verstappen continues to be your driver of choice for a DRS boost, though some of you have dropped him. He has 25 DRS boost selections this week. But the favour is certainly blowing towards Lando Norris who has shot up to second place with 13 selections ahead of Ferrari's Charles Leclerc with 11 in third place. Just a singular wildcard and auto pilot token used this week, many of you saving them for the key races this year.

In [ ]:
count_files = [
    'LeagueCounts_Driver_Bar.png',
    'LeagueCounts_Constructor_Bar.png',
    'LeagueCounts_DRS Boost_Bar.png',
    'LeagueCounts_Extra DRS_Bar.png',
    'LeagueCounts_Perks_Bar.png']
directory_path = Path(f'{root}/Data/{year}/Figures/{race}')
file_paths = [
    Path(f'{directory_path}/{race}_{file}') for file in count_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None, None, None]
In [ ]:
count_files = [
    'LeagueSumCounts_Driver.png',
    'LeagueSumCounts_Constructor.png',
    'LeagueSumCounts_DRS Boost.png',
    'LeagueSumCounts_Extra DRS.png',
    'LeagueSumCounts_Perks.png']
directory_path = Path(f'{root}/Data/{year}/Figures/{race}')
file_paths = [
    Path(f'{directory_path}/{race}_{file}') for file in count_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None, None, None]

For more figures, please see the Facebook group album.

In [ ]:
subprocess.run(["python", "league_prizes.py", f'{year}'])
Out[ ]:
CompletedProcess(args=['python', 'league_prizes.py', '2024'], returncode=0)

Prizes¶

The Spanish Grand Prix was a spot prize weekend for the lowest score of the week, named "Madrid Will Be Better". The award this week is a tie between Patrick and Stuart, with their teams Racing No Points and Ferrari Strategists both scoring 32. It's the first time we've had a tie for a spot prize and thankfully my code picked it up, which is nice to know that it works. The protocol is to split the prize between the number of winners, so congratulations on your 0.5% prize boys.

Austria is our next race, and it's a sprint weekend, so we are back to the sprint king award. Currently, that is being led by Josh and Siemens McLaren West with 741 points, he's also in second place with Petrobras Williams RBS F1 and 666 points. Can anyone topple Josh's reign in the Sprint Championship this weekend? Only time will tell.

In [ ]:
directory_path = Path(f'{root}/Data/{year}/Figures/Prizes')
file_paths = [
    Path(f'{directory_path}/{file}') for file in
    os.listdir(directory_path) if f'{race}' in file]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
Out[ ]:
[None]

F1 Play¶

Due to me forgetting when the race started this week, I also forgot to do my predictions before the start of the race. Ironically I predicted the top three exactly and would have scored a handful of points with the predictions I made, as it turns out, for Austria. Nevertheless, Tim did not forget and takes the win this week with 7/10 correctly predicted. Stuart also bagged 4 crucial points. Matty and Josh scored 0/10.

That takes the scores to:

Stuart - 28

Josh - 31

Matty - 15

Tim - 28

In [ ]:
F1_play = {
    "Stuart S": [3, 5, 2, 4, 0, 2, 0, 3, 5, 4],
    "Matty J": [2, 2, 0, 0, 3, 3, 0, 2, 3, 0],
    "Josh M": [2, 3, 2, 6, 3, 3, 3, 2, 7, 0],
    "Tim W": [0, 3, 3, 0, 2, 3, 4, 4, 2, 7]}
io.save_json_dicts(
    out_path=Path(f'{root}/Data/{year}/F1_Play.json'),
    dictionary=F1_play)
subprocess.run(["python", "F1_play.py", f'{year}'])
points_files = [
    'Points.png',
    'Sum Points.png',
    'Average Points.png']
directory_path = Path(f'{root}/Data/{year}/Figures/F1_Play')
file_paths = [Path(f'{directory_path}/{race}_F1Play_{file}') for file in points_files]
[io.display_img(file_path=path, width=1200, height=720) for path in file_paths]
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[ ]:
[None, None, None]

Next Up¶

Next up is the Austrian Grand Prix at the end of the week. Austria is a sprint weekend and the weather is due to be horrendous. Sprint Qualifying will be on the Friday at 15:30 BST, with the Sprint on Saturday morning at 11:00 BST. Qualifying then in the afternoon as usual and the race on Sunday. Austria is of course part of the sprint king award, so be sure to get your teams sorted. It's usually quite a good race, despite the simple nature of the circuit, so I am looking forward to this one for sure. And maybe I'll even try to catch the start of the race, because that's always the best bit, who knows.